How to project objects

var defaultStyle = new ol.style.Style({
    fill: new ol.style.Fill({
	    color: 'rgba(0, 255, 0, 0.1)'
    }),
    stroke: new ol.style.Stroke({
        color: 'rgba(0, 255, 0, 1)',
        width: 4
    }),
    image: new ol.style.Circle({
        radius: 5,
        fill: new ol.style.Fill({
	        color: 'rgba(0, 255, 0, 0.7)'
        }),
        stroke: new ol.style.Stroke({
            color: 'rgba(0, 255, 0, 1)',
            width: 1
        }),
    })
});

//Add layers with features that will be projected on the image
function addProjectionLayers() {

	//some features to project
	var point = new ol.Feature(new ol.geom.Point([2120050.997001601, 6025134.1240540715]));
	
	var line = new ol.Feature(new ol.geom.LineString([[2120066.7758608386, 6025129.492230156], [2120082.3013773034, 6025139.587551411]]));
	
	var polygon = new ol.Feature(new ol.geom.Polygon([[[2120066.782223294, 6025144.500999055], [2120059.590256579, 6025117.872541881], [2120050.816009205, 6025192.095483984], [2120066.782223294, 6025144.500999055]]]));

	var pointsLayer = new ol.layer.Vector({
	    source: new ol.source.Vector({
		    features: [point]
	    }),
	    style: defaultStyle,
	    name: 'Points Layer',
	    id: "pointsLayer"
	});
	
	map.addLayer(pointsLayer);
	
	var linesLayer = new ol.layer.Vector({
	    source: new ol.source.Vector({
		    features: [line]
	    }),
	    style: defaultStyle,
	    name: 'Lines Layer',
	    id: "linesLayer"
	});
	
	map.addLayer(linesLayer);
	
	var polygonsLayer = new ol.layer.Vector({
	    source: new ol.source.Vector({
		    features: [polygon]
	    }),
	    style: defaultStyle,
	    name: 'Polygons Layer',
	    id: "polygonsLayer"
	});
	map.addLayer(polygonsLayer);
	
	/** To project and store settings for a layer we use some Imajnet SDK functions
	 * 
	 *  @id {String} must be a unique value for a layer
	 *  @groundProjection {Boolean} if the layer is projected on the ground
	 *  @heightOffset {Float} offset for projected objects 
	 *  
	 *  Lines layer will not be projected because it isn't added to the projected layers
	 */
	
	ImajnetProjection.addProjectedLayer({
		id: pointsLayer.get('id'),
		groundProjection: true,
		heightOffset: 0
	});
	
	ImajnetProjection.addProjectedLayer({
		id: polygonsLayer.get('id'),
		groundProjection: true,
		heightOffset: 0
	});
	
}

/**
 * Get map projections that will pe drawn on the image.
 * @param position - current imajnet position
 * @return {Object} A jquery deferred object that once resolved will return an array of objects
 */
ImajnetPlugin.getProjectionCandidates = function(position) {
	var result = jQuery.Deferred();

	//Imajnet function that will get the constraint from which the features will be projected
	var constraintGeometry = ImageControler.currentPhotogrammetry.getProjectionConstraint(position);

	//{arse coordinates
	for(var i = 0; i < constraintGeometry.length; i++) {
		constraintGeometry[i] = ol.proj.transform([constraintGeometry[i].x, constraintGeometry[i].y], wgs84, webMercator);
	}
	var triangle = new ol.Feature(new ol.geom.Polygon([constraintGeometry]));

	// Build an array with all the layers we want to project
	var layers = new Array();
	layers.push(getLayerByName('Points Layer'));
	layers.push(getLayerByName('Lines Layer'));
	layers.push(getLayerByName('Polygons Layer'));

	var format = new ol.format.GeoJSON();
	var intersectedFeatures = new Array();
	
	//loop over all the layers with features to project
	for(var layer in layers) {
		var features = layers[layer].getSource().getFeatures();
	//Loop over the features and check if they are in the constraint geometry
		for(var i = 0; i < features.length; i++) {	
			//An external library that checks for intersection between the feature and the constraint
			var intersection = turf.intersect(format.writeFeatureObject(triangle), format.writeFeatureObject(features[i]));

			//If an intersection is found add the feature to objects that need to be projected
			if(intersection) {
				var geometry = features[i].clone().getGeometry();
				geometry.transform(webMercator, wgs84);
				var coordinates = geometry.getCoordinates();
				var type = geometry.getType();

				//The objects that will be projected must have a feature, a geometry(coordinates) a style and a layerId

				if(type === 'Point') {
					intersectedFeatures.push({
					    feature: features[i],
					    geometry: new Array({
					        lon: coordinates[0],
					        lat: coordinates[1]
					    }),
					    style: getStyleObjectForProjection(features[i]),
					    layerId: layers[layer].get('id')
					});
				} else if(type === 'LineString') {
					var pointsArray = new Array();
					for(var k = 0; k < coordinates.length; k++) {
						pointsArray.push({
						    lon: coordinates[k][0],
						    lat: coordinates[k][1]
						})
					}
					intersectedFeatures.push({
					    feature: features[i],
					    geometry: pointsArray,
					    style: getStyleObjectForProjection(features[i]),
					    layerId: layers[layer].get('id')
					})
				} else if(type === 'Polygon') {
					var pointsArray = new Array();
					coordinatesPolygon = coordinates[0];
					for(var k = 0; k < coordinatesPolygon.length; k++) {
						pointsArray.push({
						    lon: coordinatesPolygon[k][0],
						    lat: coordinatesPolygon[k][1]
						})
					}
					intersectedFeatures.push({
					    feature: features[i],
					    geometry: pointsArray,
					    style: getStyleObjectForProjection(features[i]),
					    layerId: layers[layer].get('id')
					})
				}
			}
		}
	}
	result.resolve(intersectedFeatures);
	return result.promise();

};


function getStyleFromFeature(feature) {

	var style = feature.getStyle();
	if(!style) {
		style = defaultStyle;
	}
	if(!jQuery.isArray(style)) {
		style = [style];
	}

	return style;

}

//Function that will return the feature's style in to imajnet format so that it can be drawn in to the image
function getStyleObjectForProjection(feature) {
	var featureStyles = getStyleFromFeature(feature);
	var styleProjections = new Array();
	var type = feature.getGeometry().getType();
	var fill = null;
	var stroke = null;
	jQuery.each(featureStyles, function(key, value) {
		if(type != "Point") {
			fill = value.getFill();
			stroke = value.getStroke();
			styleProjections.push({
			    strokeColor: stroke ? stroke.getColor() : '#000000',
			    strokeLinecap: stroke.getLineCap(),
			    strokeWidth: stroke ? stroke.getWidth() : 2,
			    fill: fill ? fill.getColor() : null
			})
		} else if(type === 'Point') {
			var style = {}
			image = value.getImage();
			if(image instanceof ol.style.Icon) {
				style.externalGraphic = image.getSrc();
			} else {
				fill = image.getFill();
				stroke = image.getStroke();
				var radius = image.getRadius();
			}
			if(stroke) {
				style.strokeColor = stroke.getColor();
				style.strokeWidth = stroke.getWidth();
			}
			if(fill) {
				style.fillColor = fill.getColor();
				style.fill = true;
			}
			if(image instanceof ol.style.RegularShape) {
				var points = image.getPoints();
				var radius2 = image.getRadius2();
				var angle = image.getAngle();
				if(radius2 != radius) {
					points = points / 2;
				}
				if(points == 4) {
					if(radius2 == 0) {
						style.graphicName = 'cross';
					} else {
						style.graphicName = 'square';
					}
				} else if(points == 3) {
					style.graphicName = 'triangle';
				}
			}

			style.pointRadius = radius;
			styleProjections.push(style)
		}
	});
	return styleProjections;
}

//Helper functions to highlight the projections
ImajnetPlugin.onFeatureMouseOver = function(featureWrapper) {
    highlightFeature(featureWrapper.getFeature());
};

ImajnetPlugin.onFeatureMouseOut = function(featureWrapper) {
    removeSelect(featureWrapper.getFeature());
};

function removeSelect(feature) {
	if(!feature.get('isSelected')) {
		return;
	}
	feature.getStyle().pop();
	feature.setStyle(feature.getStyle());
	feature.set('isSelected', false)
}

function highlightFeature(feature) {
	if(feature.get('isSelected')) {
		return;
	}
	var type = feature.getGeometry().getType();
	var style = getStyleFromFeature(feature);
	style.push(selectStyle(type));
	feature.setStyle(style);
	feature.set('isSelected', true);

}

function selectStyle(type) {
	if(type == 'Point') {
		return new ol.style.Style({
		    image: new ol.style.Circle({
		        radius: 6,
		        fill: new ol.style.Fill({
			        color: 'rgba(52, 152, 219, 0.5)'
		        }),
		        stroke: new ol.style.Stroke({
		            color: 'blue',
		            width: 3
		        })
		    }),
		    zIndex: 999
		});
	} else if(type == 'LineString') {
		return new ol.style.Style({
		    stroke: new ol.style.Stroke({
		        color: 'rgba(52, 152, 219, 0.5)',
		        width: 16
		    }),
		    zIndex: 999
		});
	} else if(type == 'Polygon') {
		return new ol.style.Style({
		    stroke: new ol.style.Stroke({
		        color: 'rgba(0, 0, 255, 1)',
		        width: 3
		    }),
		    fill: new ol.style.Fill({
			    color: 'rgba(52, 152, 219, 0.5)'
		    }),
		    zIndex: 999
		});
	}
}